package cn.stylefeng.guns.modular.basic.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.core.util.CangGuanRoleId;
import cn.stylefeng.guns.modular.basic.entity.BasicCarrier;
import cn.stylefeng.guns.modular.basic.entity.BasicOperate;
import cn.stylefeng.guns.modular.basic.entity.BasicPrivatecar;
import cn.stylefeng.guns.modular.basic.mapper.BasicPrivatecarMapper;
import cn.stylefeng.guns.modular.basic.model.params.BasicDriverParam;
import cn.stylefeng.guns.modular.basic.model.params.BasicOperateParam;
import cn.stylefeng.guns.modular.basic.model.params.BasicPrivatecarParam;
import cn.stylefeng.guns.modular.basic.model.result.BasicDriverResult;
import cn.stylefeng.guns.modular.basic.model.result.BasicOperateResult;
import cn.stylefeng.guns.modular.basic.model.result.BasicPrivatecarResult;
import cn.stylefeng.guns.modular.basic.service.BasicCarrierService;
import cn.stylefeng.guns.modular.basic.service.BasicDriverService;
import cn.stylefeng.guns.modular.basic.service.BasicOperateService;
import  cn.stylefeng.guns.modular.basic.service.BasicPrivatecarService;
import cn.stylefeng.guns.modular.order.model.params.OrderTransportParam;
import cn.stylefeng.guns.sys.modular.system.entity.User;
import cn.stylefeng.guns.sys.modular.system.model.UserDto;
import cn.stylefeng.guns.sys.modular.system.service.UserService;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.util.ToolUtil;

/**
 * 自有车档案表 服务实现类
 */
@Service
public class BasicPrivatecarServiceImpl extends ServiceImpl<BasicPrivatecarMapper, BasicPrivatecar> implements BasicPrivatecarService {

    @Override
    public void add(BasicPrivatecarParam param){
        BasicPrivatecar entity = getEntity(param);
        this.save(entity);
    }

    @Override
    public void delete(BasicPrivatecarParam param){
        this.removeById(getKey(param));
    }

    @Override
    public void update(BasicPrivatecarParam param){
        BasicPrivatecar oldEntity = getOldEntity(param);
        BasicPrivatecar newEntity = getEntity(param);
        ToolUtil.copyProperties(newEntity, oldEntity);
        this.updateById(newEntity);
    }

    @Override
    public BasicPrivatecarResult findBySpec(BasicPrivatecarParam param,Long deptId,Long operateId){
        return this.baseMapper.findBySpec(param,deptId, operateId);
    }

    @Override
    public List<BasicPrivatecarResult> findListBySpec(BasicPrivatecarParam param,Long deptId,Long operateId){
        return this.baseMapper.findListBySpec(param,deptId,operateId);
    }

    @Override
    public List<BasicPrivatecarResult> findBySpecList(BasicPrivatecarParam param, Long operateId) {
        return this.baseMapper.findBySpecList(param, operateId);
    }

    @Override
    public LayuiPageInfo findPageBySpec(BasicPrivatecarParam param,String condition, Long deptId,String channeltype, Long operateId){
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageList(pageContext, param,condition,deptId,channeltype, operateId);
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public LayuiPageInfo appFindPageBySpec(BasicPrivatecarParam param, Long deptId, Long operateId){
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.appFindPageBySpec(pageContext, param,deptId, operateId);
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public LayuiPageInfo findPlatooncarPageBySpec(BasicPrivatecarParam param,String condition, Long operateId){
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.findPlatooncarPageBySpec(pageContext, param, condition, operateId);
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public BasicPrivatecarResult findByName(String name, Long operateId) {
        return this.baseMapper.findByName(name,operateId);
    }

    private Serializable getKey(BasicPrivatecarParam param){
        return param.getId();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private BasicPrivatecar getOldEntity(BasicPrivatecarParam param) {
        return this.getById(getKey(param));
    }

    private BasicPrivatecar getEntity(BasicPrivatecarParam param) {
        BasicPrivatecar entity = new BasicPrivatecar();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }

	@Override
	public boolean findTwoByOrder(OrderTransportParam orderTransportParam,Long operateId) {
		List<BasicPrivatecarResult> list = baseMapper.findTwoByOrder(orderTransportParam,operateId);
		if (list.size()>=1) {
			return true;
		} else {
			return false;
		}
	}
    
	private static String getCellValue(Cell cell) {
        if (cell == null) {
            return "";
        }
        if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
            if (DateUtil.isCellDateFormatted(cell)) {
                return HSSFDateUtil.getJavaDate(cell.getNumericCellValue()).toString();
            } else {
                return new BigDecimal(cell.getNumericCellValue()).toString();
            }
        } else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
            return StringUtils.trimToEmpty(cell.getStringCellValue());
        } else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
            return StringUtils.trimToEmpty(cell.getCellFormula());
        } else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
            return "";
        } else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
            return String.valueOf(cell.getBooleanCellValue());
        } else if (cell.getCellType() == Cell.CELL_TYPE_ERROR) {
            return "ERROR";
        } else {
            return cell.toString().trim();
        }
    }

	@Resource
	BasicDriverService basicDriverService;
	
	@Resource
	BasicOperateService basicOperateService;

	@Resource
    private BasicCarrierService basicCarrierService;

	@Override
	@Transactional(rollbackFor = Exception.class,timeout=80)
	public ResponseData getExceldata(MultipartFile file, BasicPrivatecarParam basicPrivatecarParam, ResponseData data) throws IOException {
		User meuser = userService.getcurrentUser();
		
    	Object privatecarFleetId = basicPrivatecarParam.getPrivatecarFleetId();
    	BasicCarrier basicCarrier = new BasicCarrier();
    	if(privatecarFleetId != null) {
    		basicCarrier = basicCarrierService.getById(Integer.parseInt(privatecarFleetId.toString()));
    	}
    	Object operateId = basicPrivatecarParam.getOperateId();
    	BasicOperate basicOperate = new BasicOperate();
    	if(basicOperate != null) {
    		basicOperate = basicOperateService.getById(Integer.parseInt(operateId.toString()));
    	}
		
		String fileName = file.getOriginalFilename();
		List<BasicPrivatecarParam> list = new ArrayList<BasicPrivatecarParam>();
		
		if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
			data.setMessage("Incorrect Upload File Format");
			data.setSuccess(false);
        }

		boolean isExcel2003 = true;
        if (fileName.matches("^.+\\.(?i)(xlsx)$")) {
            isExcel2003 = false;
        }
        InputStream is = file.getInputStream();
        Workbook wb = null;
        if (isExcel2003) {
            wb = new HSSFWorkbook(is);
        } else {
            wb = new XSSFWorkbook(is);
        }
        Sheet sheet = wb.getSheetAt(0);
        
        for (int r = 1; r <= sheet.getLastRowNum()+1; r++) {
        	Row row = sheet.getRow(r);
            if (row == null){
                continue;
            }
            BasicPrivatecarParam bd = new BasicPrivatecarParam();
            if(basicOperate != null) {
            	bd.setOperateId(basicPrivatecarParam.getOperateId());
            	bd.setOperateName(basicOperate.getOperateName());
            }
        	if (privatecarFleetId!=null) {
        		bd.setPrivatecarFleetId(Integer.parseInt(privatecarFleetId.toString()));
        		bd.setPrivatecarFleetName(basicCarrier.getCarrierName());
        		bd.setSettlement("Carrier");
        		bd.setPayee(basicCarrier.getPayee());
        		bd.setBank(basicCarrier.getBank());
        		bd.setBankAddress(basicCarrier.getBankAddress());
        		bd.setBankAccount(basicCarrier.getBankAccount());
        		bd.setBankNo(basicCarrier.getBankNo());
        		bd.setCycle(basicCarrier.getCycle());
        		bd.setTaxRate(basicCarrier.getTaxRate());
        		bd.setOilCardNumber(basicCarrier.getOilCardNumber());
    		}
            bd.setDeliverId(meuser.getDeliverId());
            bd.setDeptId(meuser.getDeptId());
            bd.setPrivatecarVhiclegenus(basicPrivatecarParam.getPrivatecarVhiclegenus());
            bd.setPrivatecarState("IDLE");
            bd.setCreateTime(new Date());

            String  privatecarNumber = getCellValue(row.getCell(0));
            if (ToolUtil.isNotEmpty(privatecarNumber)) {
            	bd.setPrivatecarNumber(privatecarNumber);
			} 
            
            String  privatecarCarnumber = getCellValue(row.getCell(1));
            if (ToolUtil.isNotEmpty(privatecarCarnumber)) {
                BasicPrivatecarParam basicPrivatecarParam1 = new BasicPrivatecarParam();
                basicPrivatecarParam1.setPrivatecarCarnumber(privatecarCarnumber);
                basicPrivatecarParam1.setDeliverId(meuser.getDeliverId());
                List<BasicPrivatecarResult> list2 = findBySpecList(basicPrivatecarParam1,null);
                if (list2.size() >0){
                	continue;
                } else {
                	bd.setPrivatecarCarnumber(privatecarCarnumber);
                }
			} else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
	    		return ResponseData.error("License Plate Number cannot be empty");
			}

            String  privatecarColour = getCellValue(row.getCell(2));
            if (ToolUtil.isNotEmpty(privatecarColour)) {
				bd.setPrivatecarColour(privatecarColour);
			}

            String  privatecarType = getCellValue(row.getCell(3));
            if (ToolUtil.isNotEmpty(privatecarType)) {
				bd.setPrivatecarType(privatecarType);
			} else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
	    		return ResponseData.error("Vehicle Type cannot be empty");
			}

            String  privatecarSurevolume = getCellValue(row.getCell(4));
            if (ToolUtil.isNotEmpty(privatecarSurevolume)) {
        		BigDecimal privatecarSurevolumebig = new BigDecimal(privatecarSurevolume).setScale(2, BigDecimal.ROUND_HALF_DOWN);
        		bd.setPrivatecarSurevolume(privatecarSurevolumebig.toString());
			} else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
	    		return ResponseData.error("Approved Loading Volume cannot be empty");
			}
            
            String  privatecarCarlong = getCellValue(row.getCell(5));
            if (ToolUtil.isNotEmpty(privatecarCarlong)) {
				bd.setPrivatecarCarlong(privatecarCarlong);
			} 
            
            String  privatecarCarwide = getCellValue(row.getCell(6));
            if (ToolUtil.isNotEmpty(privatecarCarwide)) {
				bd.setPrivatecarCarwide(privatecarCarwide);
			} 
            
            String  privatecarCarhigh = getCellValue(row.getCell(7));
            if (ToolUtil.isNotEmpty(privatecarCarhigh)) {
				bd.setPrivatecarCarhigh(privatecarCarhigh);
			} 
            
            String  privatecarCarheavy = getCellValue(row.getCell(8));
            if (ToolUtil.isNotEmpty(privatecarCarheavy)) {
				bd.setPrivatecarCarheavy(privatecarCarheavy);
			} 

            String  driver1 = getCellValue(row.getCell(9));
            String  tel1 = getCellValue(row.getCell(10));
            if (ToolUtil.isNotEmpty(driver1)||ToolUtil.isNotEmpty(tel1)) {
            	BasicDriverParam basicDriverParam = new BasicDriverParam();
            	basicDriverParam.setDriverName(driver1);
            	basicDriverParam.setTel(tel1);
            	basicDriverParam.setDeliverId(meuser.getDeliverId());
            	BasicDriverResult basicDriverResult = basicDriverService.findBySpec(basicDriverParam,null);
            	if (basicDriverResult == null) {
    		    	User user = userService.getByAccount(tel1);
    		    	if(user == null) {
    			        //添加账号
    			        UserDto userDto = new UserDto();
    			        userDto.setAccount(tel1);
    			        userDto.setPassword("111111");
    			        userDto.setName(driver1);
    			        userDto.setSex("M");
    			        userDto.setPhone(tel1);
    			        userDto.setRoleId(CangGuanRoleId.SJRoleId.toString());
    			        userDto.setDeptId(meuser.getDeptId());
    			        userDto.setStatus("ENABLE");
    			        userDto.setDeliverId(meuser.getDeliverId());
    			        userDto.setDeliverName(meuser.getDeliverName());
    			        userDto.setOperateId(meuser.getOperateId());
    			        userService.addUser(userDto);
    			        user = userService.getByAccount(tel1);
    			        basicDriverParam.setUserId(user.getUserId());
    		    	} else {
    	                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
    		    		return ResponseData.error(tel1+"Already Registered");
    		    	}
    		    	
            		if (basicOperate != null) {
            			basicDriverParam.setDriverOperateId(Integer.parseInt(basicPrivatecarParam.getOperateId().toString()));
            			basicDriverParam.setDriverOperateName(basicOperate.getOperateName());
					}
            		basicDriverParam.setDriverNumber(tel1);
            		basicDriverParam.setDeptId(meuser.getDeptId());
            		basicDriverParam.setDeliverId(meuser.getDeliverId());
            		basicDriverService.addReturnId(basicDriverParam);
            		bd.setDriverId1(Long.parseLong(basicDriverParam.getId().toString()));
				} else {
            		bd.setDriverId1(Long.parseLong(basicDriverResult.getId().toString()));
				}
				bd.setDriver1(driver1);
				bd.setTel1(tel1);
			} else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
	    		return ResponseData.error("Primary Driver and Phone Number cannot be empty");
			}
            
            list.add(bd);
        }
        if (list.size() > 0) {
        	saveBatchList(list);
		}
		
        data.setSuccess(true);
		return data;
	}

    @Resource
    private UserService userService;

	@Override
	public boolean saveBatchList(List<BasicPrivatecarParam> list) {
		return this.baseMapper.saveBatchList(list);
	}

	@Override
	public List<BasicPrivatecarResult> findListBySpec8(BasicPrivatecarParam param, Long deptId, Long operateId) {
		return this.baseMapper.findListBySpec8(param,deptId,operateId);
	}

}
